/**
 *It is a demo for practicing JAVA. All codes are opened source by Jian.
 */
package jian.tool.daocode.core;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import jian.tool.daocode.util.CodeDaoHelper;
import jian.tool.daocode.util.CodeEntityHelper;
import jian.tool.daocode.util.CodeFlashUtilHelper;
import jian.tool.daocode.util.TableHelper;
import jian.tool.daocode.util.TreeHelper;
import jian.tool.daocode.util.Util;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.wb.swt.SWTResourceManager;

/**
 * @author Jian
 * @date 2012-6-26
 * @version
 * 
 */
public class _Main {
	private static final int PRO_ADD = 0;
	private static final int PRO_DEL = 1;

	private static Table table;

	private static Tree tree;

	private static List<List<String>> tableContents;

	// 注意：LinkedHashMap为有序容器，HashMap为无序容器
	private final static Map<String, String> PROPERTIES = new LinkedHashMap<String, String>();

	private static String currentSelectedTable;

	/**
	 * 全选字段
	 */
	private static boolean SELECT_ALL = true;

	/**
	 * 是否需要 DBOption 标记
	 */
	private static boolean DBOPTION = false;

	private static ToolItem tltmDboption;

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		final Display display = Display.getDefault();
		final Shell roadDaoTool = new Shell();
		roadDaoTool.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		roadDaoTool.setSize(1000, 600);
		roadDaoTool.setText("Jian DAO TOOL");
		roadDaoTool.setLayout(new FillLayout(SWT.HORIZONTAL));

		Menu menu = new Menu(roadDaoTool, SWT.BAR);
		roadDaoTool.setMenuBar(menu);

		MenuItem muConn = new MenuItem(menu, SWT.CASCADE);
		muConn.setText("连接");

		Menu menu_1 = new Menu(muConn);
		muConn.setMenu(menu_1);

		MenuItem muConnNew = new MenuItem(menu_1, SWT.NONE);
		muConnNew.setText("新建");

		new MenuItem(menu, SWT.SEPARATOR);

		MenuItem muHelp = new MenuItem(menu, SWT.CASCADE);
		muHelp.setText("帮助");

		Menu menu_2 = new Menu(muHelp);
		muHelp.setMenu(menu_2);

		MenuItem muAbout = new MenuItem(menu_2, SWT.NONE);
		muAbout.setText("关于");

		Composite composite = new Composite(roadDaoTool, SWT.NONE);
		composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		GridLayout gl_composite = new GridLayout(1, false);
		gl_composite.horizontalSpacing = 0;
		gl_composite.verticalSpacing = 0;
		gl_composite.marginWidth = 0;
		gl_composite.marginHeight = 0;
		composite.setLayout(gl_composite);

		ToolBar toolBar = new ToolBar(composite, SWT.FLAT | SWT.RIGHT);
		toolBar.setBackground(SWTResourceManager
				.getColor(SWT.COLOR_WIDGET_BACKGROUND));
		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));

		ToolItem toolConn = new ToolItem(toolBar, SWT.NONE);
		toolConn.setImage(SWTResourceManager
				.getImage("resource\\images\\conn.jpg"));

		ToolItem toolUser = new ToolItem(toolBar, SWT.NONE);
		toolUser.setImage(SWTResourceManager
				.getImage("resource\\images\\user.jpg"));

		SashForm sashForm = new SashForm(composite, SWT.BORDER);
		sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
				1));

		Composite compConnList = new Composite(sashForm, SWT.BORDER);
		compConnList
				.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		GridLayout gl_compConnList = new GridLayout(1, false);
		gl_compConnList.verticalSpacing = 0;
		gl_compConnList.horizontalSpacing = 0;
		gl_compConnList.marginWidth = 0;
		gl_compConnList.marginHeight = 0;
		compConnList.setLayout(gl_compConnList);

		Composite composite_1 = new Composite(compConnList, SWT.NONE);
		composite_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		composite_1.setLayout(new FillLayout(SWT.HORIZONTAL));
		composite_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 1, 1));

		CLabel lblNewLabel = new CLabel(composite_1, SWT.NONE);
		lblNewLabel.setText("Connections");

		Composite composite_2 = new Composite(compConnList, SWT.NONE);
		composite_2.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		composite_2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));
		GridLayout gl_composite_2 = new GridLayout(1, false);
		gl_composite_2.verticalSpacing = 0;
		gl_composite_2.marginWidth = 0;
		gl_composite_2.marginHeight = 0;
		gl_composite_2.horizontalSpacing = 0;
		composite_2.setLayout(gl_composite_2);

		tree = new Tree(composite_2, SWT.BORDER);
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		List<String> databases = TreeHelper.getDatabases();
		for (int i = 0; i < databases.size(); i++) {
			TreeItem dbItem = new TreeItem(tree, SWT.NONE);
			dbItem.setData("type", "DB");
			dbItem.setText(databases.get(i));
			List<String> tables = TreeHelper.getTables(databases.get(i));
			for (int j = 0; j < tables.size(); j++) {
				TreeItem treeItem = new TreeItem(dbItem, SWT.NONE);
				treeItem.setText(tables.get(j));
				treeItem.setData("type", "TABLE");

			}
		}
		final String[] titles = { "Name", "Java Type", "Sql Type", "Max Size",
				"Comment" };
		tree.addListener(SWT.Selection, new Listener() {

			@Override
			public void handleEvent(Event event) {
				TreeItem[] selection = tree.getSelection();
				if (selection.length > 0
						&& selection[0].getData("type").equals("TABLE")) {
					// System.out.println(selection[0] + "=="
					// + selection[0].getParentItem());
					PROPERTIES.clear();
					currentSelectedTable = selection[0].getText();
					tableContents = null;
					table.removeAll();
					tableContents = TableHelper.showResultSetMetaData(
							selection[0].getParentItem().getText(),
							selection[0].getText());

					for (int i = 0; i < tableContents.size(); i++) {

						TableItem t_item = new TableItem(table, SWT.NONE);
						for (int j = 0; j < titles.length; j++) {
							t_item.setText(j, tableContents.get(i).get(j));
							t_item.setChecked(true);
						}
						String clickItemName = t_item.getText();
						@SuppressWarnings("unused")
						String typeJavaName = t_item.getText(1);
						String sqlType = t_item.getText(2);
						String comment = t_item.getText(4);
						updateProperties(
								Util.changeFirstToLowerCase(clickItemName),
								Util.getJavaTypeName(sqlType) + "." + comment,
								PRO_ADD);
					}

					for (int k = 0; k < titles.length; k++) {
						table.getColumn(k).pack();
					}
					SELECT_ALL = true;

					tltmDboption.setSelection(false);
					DBOPTION = false;
				}

			}
		});

		Composite compContentShow = new Composite(sashForm, SWT.BORDER);
		compContentShow.setBackground(SWTResourceManager
				.getColor(SWT.COLOR_WHITE));
		GridLayout gl_compContentShow = new GridLayout(1, false);
		gl_compContentShow.verticalSpacing = 0;
		gl_compContentShow.marginWidth = 0;
		gl_compContentShow.marginHeight = 0;
		gl_compContentShow.horizontalSpacing = 0;
		compContentShow.setLayout(gl_compContentShow);

		ToolBar codeBar = new ToolBar(compContentShow, SWT.FLAT | SWT.RIGHT);
		codeBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1,
				1));

		/* 点击选中当前表中所有字段 */
		ToolItem tltmSelectall = new ToolItem(codeBar, SWT.NONE);
		tltmSelectall.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (currentSelectedTable == null || table == null)
					return;
				SELECT_ALL = !SELECT_ALL;
				for (TableItem item : table.getItems()) {
					String clickItemName = item.getText();
					String typeJavaName = item.getText(1);
					System.err.println("====" + clickItemName);
					item.setChecked(SELECT_ALL);
					updateProperties(clickItemName,
							typeJavaName.split("\\.")[2], SELECT_ALL ? PRO_ADD
									: PRO_DEL);

				}

			}
		});
		tltmSelectall.setText("SelectAll");

		/* 点击 【生成实体代码】 */
		ToolItem codeEntity = new ToolItem(codeBar, SWT.NONE);
		codeEntity.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (currentSelectedTable == null || table == null)
					return;
				/* 生成代码预览窗口, 获取焦点 */
				final Shell codeDialog = new Shell(roadDaoTool, SWT.DIALOG_TRIM
						| SWT.APPLICATION_MODAL);
				Point pt = display.getCursorLocation();
				codeDialog.setLocation(pt);
				codeDialog.setLayout(new FillLayout());
				codeDialog.setText("Entity 代码");

				final Text text = new Text(codeDialog, SWT.BORDER | SWT.MULTI
						| SWT.V_SCROLL | SWT.H_SCROLL);

				String clzName = Util.getClassName(currentSelectedTable);

				/* 包名暂时写死... @TODO 包名与类名均需提供默认命名, 并提供界面给用户编辑 */
				String code = CodeEntityHelper.generateEntityCode(
						Util.ENTITY_PACKAGE, clzName, PROPERTIES, DBOPTION);
				if (code == null || code.length() == 0) {
					return;
				}
				text.setText(code);

				codeDialog.setSize(600, 500);
				codeDialog.open();
			}
		});
		codeEntity.setText("Code_Entity");

		/* 生成 Dao 层 */
		ToolItem codeDao = new ToolItem(codeBar, SWT.NONE);
		codeDao.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {

				if (currentSelectedTable == null || table == null)
					return;
				/* 生成代码预览窗口, 获取焦点 */
				final Shell codeDialog = new Shell(roadDaoTool, SWT.DIALOG_TRIM
						| SWT.APPLICATION_MODAL);
				Point pt = display.getCursorLocation();
				codeDialog.setLocation(pt);
				codeDialog.setLayout(new FillLayout());
				codeDialog.setText("Dao 代码");

				final Text text = new Text(codeDialog, SWT.BORDER | SWT.MULTI
						| SWT.V_SCROLL | SWT.H_SCROLL);

				String clzName = Util.getClassName(currentSelectedTable);
				String code = CodeDaoHelper.generateDaoCode(clzName,
						Util.DAO_PACKAGE, clzName + "Dao");
				if (code == null || code.length() == 0) {
					return;
				}
				text.setText(code);

				codeDialog.setSize(600, 500);
				codeDialog.open();
			}
		});
		codeDao.setText("Code_Dao");

		/* 生成DaoImpl */
		ToolItem tltmCodedaoimpl = new ToolItem(codeBar, SWT.NONE);
		tltmCodedaoimpl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (currentSelectedTable == null || table == null)
					return;
				/* 生成代码预览窗口, 获取焦点 */
				final Shell codeDialog = new Shell(roadDaoTool, SWT.DIALOG_TRIM
						| SWT.APPLICATION_MODAL);
				Point pt = display.getCursorLocation();
				codeDialog.setLocation(pt);
				codeDialog.setLayout(new FillLayout());
				codeDialog.setText("DaoImpl 代码");

				final Text text = new Text(codeDialog, SWT.BORDER | SWT.MULTI
						| SWT.V_SCROLL | SWT.H_SCROLL);

				
				String code = CodeDaoHelper.generateDaoImplCode(currentSelectedTable,
						Util.DAOIMPL_PACKAGE, PROPERTIES);
				if (code == null || code.length() == 0) {
					return;
				}
				text.setText(code);

				codeDialog.setSize(800, 800);
				codeDialog.open();
			}
		});
		tltmCodedaoimpl.setText("Code_DaoImpl");

		/* 生成业务逻辑层代码 */
		ToolItem tltmCodebll = new ToolItem(codeBar, SWT.NONE);
		tltmCodebll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (currentSelectedTable == null || table == null)
					return;

			}
		});
		tltmCodebll.setText("Code_Bll");

		/* 生成 FlashUtil.java 的部分代码 */
		ToolItem tltmCodeflash = new ToolItem(codeBar, SWT.NONE);
		tltmCodeflash.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (currentSelectedTable == null || table == null)
					return;
				/* 生成代码预览窗口, 获取焦点 */
				final Shell codeDialog = new Shell(roadDaoTool, SWT.DIALOG_TRIM
						| SWT.APPLICATION_MODAL);
				Point pt = display.getCursorLocation();
				codeDialog.setLocation(pt);
				codeDialog.setLayout(new FillLayout());
				codeDialog.setText("FlashUtil 代码");

				final Text text = new Text(codeDialog, SWT.BORDER | SWT.MULTI
						| SWT.V_SCROLL | SWT.H_SCROLL);

				String clzName = Util.getClassName(currentSelectedTable);
				String code = CodeFlashUtilHelper.generateFlashUtilCode(
						clzName, PROPERTIES.keySet());
				if (code == null || code.length() == 0) {
					return;
				}
				text.setText(code);

				codeDialog.setSize(800, 800);
				codeDialog.open();
			}
		});
		tltmCodeflash.setText("Code_Flash");

		// 是否做数据库操作标记
		tltmDboption = new ToolItem(codeBar, SWT.CHECK);
		tltmDboption.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				DBOPTION = !DBOPTION;
			}
		});
		tltmDboption.setText("DBOption");

		Composite compTable = new Composite(compContentShow, SWT.NONE);
		compTable.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		compTable.setLayout(new FillLayout(SWT.HORIZONTAL));
		compTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
				1));

		table = new Table(compTable, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL
				| SWT.H_SCROLL);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		for (int i = 0; i < titles.length; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText(titles[i]);
		}

		table.addListener(SWT.Selection, new Listener() {

			@Override
			public void handleEvent(Event e) {
				String clickItemName = ((TableItem) e.item).getText();
				String typeJavaName = ((TableItem) e.item).getText(1);
				System.err.println("====" + clickItemName);
				((TableItem) e.item).setChecked(!((TableItem) e.item)
						.getChecked());
				updateProperties(clickItemName, typeJavaName.split("\\.")[2],
						PRO_ADD);
			}
		});

		sashForm.setWeights(new int[] { 1, 4 });

		roadDaoTool.open();
		roadDaoTool.layout();
		while (!roadDaoTool.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	private static void updateProperties(String key, String value, int doType) {
		switch (doType) {
		case PRO_ADD:
			if (!PROPERTIES.containsKey(key)) {
				PROPERTIES.put(key, value);
			}
			break;
		case PRO_DEL:
			if (PROPERTIES.containsKey(key)) {
				PROPERTIES.remove(key);
			}
		default:
			break;
		}
	}

}
